import math
import unittest
from electrostaticvacuum import Vector, PointCharge, ElectrostaticField


class ElectrostaticFieldTest(unittest.TestCase):
    def test_k(self):
        o = PointCharge(Vector(0, 0), 1)
        th_fo = PointCharge(Vector(3, 4), -2)
        flt = PointCharge(Vector(213.1231, -123.12312), 2.31)
        field1 = ElectrostaticField([o, th_fo, flt], k=12345)
        field2 = ElectrostaticField([o, th_fo])

        self.assertAlmostEqual(12345, field1.k)
        self.assertAlmostEqual(8.99E9, field2.k)

    def test_get_charges(self):
        o = PointCharge(Vector(0, 0), 1)
        th_fo = PointCharge(Vector(3, 4), -2)
        flt = PointCharge(Vector(213.1231, -123.12312), 2.31)
        field1 = ElectrostaticField([o, th_fo, flt], k=12345)
        field2 = ElectrostaticField([o, th_fo])
        self.assertSequenceEqual([o, th_fo, flt], list(field1.get_charges()))
        self.assertSequenceEqual([o, th_fo], list(field2.get_charges()))

    def test_get_potential(self):
        o = PointCharge(Vector(0, 0), 1)
        th_fo = PointCharge(Vector(3, 4), -2)
        flt = PointCharge(Vector(213.1231, -123.12312), 2.31)
        field1 = ElectrostaticField([o, th_fo, flt], k=12345)
        field2 = ElectrostaticField([o, th_fo])

        self.assertAlmostEqual(float("inf"), field1.get_potential(Vector(0, 0)))
        self.assertAlmostEqual(
            5520.851836 + (-8729.233214) + 115.7925169,
            field1.get_potential(Vector(1, 2)),
            delta=1E-3
        )

        self.assertAlmostEqual(float("-inf"), field2.get_potential(th_fo))
        self.assertAlmostEqual(
            4020450224 + (-6356889963),
            field2.get_potential(Vector(1, 2)),
            delta=1E+1
        )

    def test_get_intensity(self):
        o = PointCharge(Vector(0, 0), 1)
        th_fo = PointCharge(Vector(3, 4), -2)
        flt = PointCharge(Vector(213.1231, -123.12312), 2.31)
        field1 = ElectrostaticField([o, th_fo, flt], k=12345)
        field2 = ElectrostaticField([o, th_fo])

        intensity = field1.get_intensity(Vector(0, 0))
        self.assertEqual("nan", str(intensity.x))
        self.assertEqual("nan", str(intensity.y))

        intensity = field1.get_intensity(Vector(1, 2))
        self.assertAlmostEqual(
            1104.170367 + 2182.308304 - 0.4101675279,
            intensity.x,
            delta=1E-1
        )
        self.assertAlmostEqual(
            2208.340734 + 2182.308304 + 0.2396819437,
            intensity.y,
            delta=1E-1
        )

        intensity = field2.get_intensity(th_fo)
        self.assertEqual("nan", str(intensity.x))
        self.assertEqual("nan", str(intensity.y))

        intensity = field2.get_intensity(Vector(1, 2))
        self.assertAlmostEqual(
            804090044 + 1589222491,
            intensity.x,
            delta=1E3
        )
        self.assertAlmostEqual(
            1608180067 + 1589222491,
            intensity.y,
            delta=1E3
        )


if __name__ == '__main__':
    unittest.main()
